from gameGui.SklGui import InventoryGui

class Inventory:
    """ 
    
    Class representing player's inventory, and handling interactions involving it.
    
    Names of _items in inventory can consist of lower and upper case letters 
    (the standard way of naming items is to start by upper case letter).
    
    Note on inventoryGui:
        Concept of working with GUI:
        Most players add items to inventory more frequently than actually 
        look into it. Even less frequent are cases when you look into your
        inventory and add/remove items at the same time. Because of those facts,
        types and quantities of items are stored in simple dictionary, and GUI
        is only responsible for drawing this data on the screen.
        
        GUI used for inventory can be whatever you want, but shall implement:
        * show() - for showing inventory on the screen
        * hide() - to hide from screen
        * reload(_items) - for changing the contents of on-screen inventory GUI
    
    
    Class attribs:
    _items - dictionary containing possessed _items and their quantity (keys are string, values are ints)
    _directObjectParent - object on which inventory GUI will be shown
    _inventoryGui - inventory GUI mentioned above;
        for more info see above
    _inventoryShown - indication if inventory is shown (True) or not (False)
    _money - integer representing value of _money that player has
    
    """
    
    _items = {}
    _directObjectParent = None
    _inventoryGui = None
    _inventoryShown = False
    _money = int(0)
    
    def __init__(self, DirectObject):
        """ Init. This method also prevents using inappropriate GUI
        (in this case inappropriate = without needed methods).
        
        params:
        DirectObject - object on which inventory GUI should be displayed.
        """
    
        self._directObjectParent = DirectObject
        self._inventoryGui = InventoryGui(self._directObjectParent)
        
####### not the most beautiful code you've ever seen, but gets the job done;
####### it checks whether the used GUI has all needed methods
        if not hasattr(self._inventoryGui, 'show'):
            raise
        
        if not hasattr(self._inventoryGui, 'hide'):
            raise
        
        if not hasattr(self._inventoryGui, 'reload'):
            raise
        
        
    def getItems(self):
        return self._items
    
    def getInventoryGui(self):
        return self._inventoryGui
    
    def getMoney(self):
        return self._money
    
    def getInventoryShown(self):
        """ Returns the state of inventory GUI (True = shown, False = hidden). """
        return self._inventoryShown
    
    def addToInventory(self, sItem, iQuantity=1):
        """ Method used for adding _items (both already existing and brand new)
            to inventory. It affect _inventoryGui.
            
            sItem - name (string) of item we want to add
            iQuantity - quantity of item(s)
        """
        
        if sItem in self._items:
            self._items[sItem] = self._items[sItem] + iQuantity
            
        else:
            self._items[sItem] = iQuantity
                
        if self._inventoryShown:
            self._inventoryGui.reload(self._items)
            
    def takeFromInventory(self, sItem, iQuantity=1):
        """ Method used for taking _items from inventory.
            It returns int values:
                * in case we requested same amount or more _items than we already have - it return a quantity that we have
                * in case we requested less _items that we have - it return requested amount
                * in case we requested _items we don't have at all - returns None (such case should be considered error!)
                
            params:
            sItem - name (string) of item we request
            iQuantity - quantity (int) of item(s)
        """
        
        if sItem in self._items:
            if iQuantity >= self._items[sItem]:
                iQuantity = self._items[sItem]
                del  self._items[sItem]
                print "not enough _items in inventory - returning everything"
                return iQuantity

            else:
                self._items[sItem] = self._items[sItem] - iQuantity
                return iQuantity
            
            if self._inventoryShown:
                self._inventoryGui.reload(self._items)
        
        else:
            print "Item \'", sItem, "\' not in inventory"
            return None
        
    def addMoney(self, iAmountOfMoney):
        """ Method adding some sum of money. 
        
        params:
        iAmountOfMoney - sum (int) of money to add
        """
        
        self._money = self._money + iAmountOfMoney
        
    def takeMoney(self, iAmountOfMoney):
        """ Method taking some money. If amount which one wants to take is
            greater than amount posessed, method returns the amount posessed
            as amount which was taken rfom player. Otherwise returns 
            amount requested to take.
            
            params:
            iAmountOfMoney - amount (int) of money requested to take from player
        """
        
        if self._money >= iAmountOfMoney:
            self._money = self._money - iAmountOfMoney
            return iAmountOfMoney
        
        else:
            iAmountOfMoney = int(self._money)
            self._money = 0
            return iAmountOfMoney
            
        
    def show(self):
        """ Method for showing inventory GUI on the screen. """

        self._inventoryGui.reload(self._items)
        self._inventoryGui.show()
        self._inventoryShown = True
        
    def hide(self):
        """ Method for hiding GUI on the screen. """
        
        self._inventoryGui.hide()
        self._inventoryShown = False
        